/*
 * @(#) LotService.java 2013-6-21 下午1:50:06
 *
 * Copyright 2013 Rockwell Automation, Inc. All rights reserved.
 * Rockwell Automation PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */package com.osi.mes.pm;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import pnuts.lang.Context;

import com.datasweep.compatibility.client.BomItem;
import com.datasweep.compatibility.client.ConsumptionSet;
import com.datasweep.compatibility.client.DCInstance;
import com.datasweep.compatibility.client.DataCollectionSet;
import com.datasweep.compatibility.client.Lot;
import com.datasweep.compatibility.client.LotFilter;
import com.datasweep.compatibility.client.Queue;
import com.datasweep.compatibility.client.Response;
import com.datasweep.compatibility.client.RuntimeDCS;
import com.datasweep.compatibility.client.Step;
import com.datasweep.compatibility.pnuts.Functions;
import com.datasweep.compatibility.ui.Time;
import com.datasweep.plantops.common.constants.filtering.IFilterComparisonOperators;
import com.datasweep.plantops.common.constants.filtering.ILotFilterAttributes;
import com.osi.mes.base.BaseService;
import com.osi.mes.utils.NumberUtils;

public class LotService extends BaseService
{

	public LotService(Context context)
	{
		super(context);
	}

	public LotService(Functions functions)
	{
		super(functions);
	}

	/**
	 * 拆肉时创建批次
	 * 
	 * @param lot
	 *            工单对应的Lot
	 * @param count
	 *            批次个数,不能大于99
	 * @return
	 */
	public Vector splitLot(Lot lot, int count)
	{
		Vector childLots = new Vector();
		BigDecimal totalQty = lot.getPreciseQuantity();
		BigDecimal eachQty = totalQty.divide(BigDecimal.valueOf(count));
		// 批次号的命名规则为： 年（4位）＋月（2位）＋日（2位）＋产线（2位）＋序列号（2位）
		for (int i = 0; i < count; i++)
		{
			String plName = lot.getProductionLineName();
			Time time = getFunctions().getDBTime();
			int year = time.getYear();
			int month = time.getMonth();
			int day = time.getDay();
			String strYear = String.valueOf(year);
			String strMonth = NumberUtils.toNumString(month);
			String strDay = NumberUtils.toNumString(day);
			String strSeq = NumberUtils.toNumString(i + 1);
			String childLotName = strYear + strMonth + strDay + plName + strSeq;
			Response response = lot.splitLot(
				childLotName, eachQty);
			if (response.isOk())
			{
				Lot childLot = (Lot) response.getResult();
				childLots.add(childLot);
			}
			else
			{
				// TODO
			}
		}

		return childLots;
	}

	/**
	 * 创建一个批次
	 * 
	 * @param lot
	 *            工单对应的Lot
	 * @param currentChildLotCount
	 *            当前工单的批次个数
	 * @param qty
	 * @return Lot 批次
	 */
	public Lot splitOneLot(Lot lot, BigDecimal qty)
	{
		String plName = lot.getProductionLineName();
		Time time = getFunctions().getDBTime();
		int year = time.getYear();
		int month = time.getMonth();
		int day = time.getDay();
		String strYear = String.valueOf(year);
		String strMonth = NumberUtils.toNumString(month);
		String strDay = NumberUtils.toNumString(day);
		String strSeq = NumberUtils.toNumString(getAllChildLotCount(lot) + 1);
		String childLotName = strYear + strMonth + strDay + plName + strSeq;
		Response response = lot.splitLot(
			childLotName, qty);
		if (response.isOk())
		{
			Lot childLot = (Lot) response.getResult();
			return childLot;
		}
		else
		{
			// TODO
			return null;
		}

	}

	/**
	 * 获得当前工单的所有批次信息
	 * @param lot
	 * @return Vector
	 */
	public Vector getAllChildLots(Lot lot)
	{
		LotFilter lotFilter = getFunctions().createLotFilter();
		lotFilter.forOrderItemKeyEqualTo(lot.getOrderItemKey());
		lotFilter.addSearchBy(
			ILotFilterAttributes.NAME, IFilterComparisonOperators.NOT_EQUAL_TO, lot.getName());
		return getFunctions().getFilteredLots(
			lotFilter);
	}
	
	/**
	 * 获得当前工单对应的所有批次原料信息
	 * @param lot
	 * @return Vector
	 */
	public Vector getAllChildLots(String orderNumber)
	{
		LotFilter lotFilter = getFunctions().createLotFilter();
		lotFilter.forUda3EqualTo(orderNumber);
		return getFunctions().getFilteredLots(
			lotFilter);
	}

	/**
	 * 记录微波解冻后原料批次温度
	 * @param lot
	 * @param temperature
	 * @return
	 */
	public Response recordMWBackLotTemperature(Lot lot, String temperature)
	{
		lot.setUDA(temperature, UDA_LOT_AFTER_MICROWAVE_TEMP);
		return lot.save();
	}
	
	/**
	 * 记录微波解冻前原料批次温度
	 * @param lot
	 * @param temperature
	 * @return
	 */
	public Response recordMWFrontLotTemperature(Lot lot, String temperature)
	{
		lot.setUDA(temperature, UDA_LOT_BEFORE_MICROWAVE_TEMP);
		return lot.save();
	}
	
	/**
	 * 某个批次在某个工序上开始生产
	 * @param lot
	 * @param operation
	 * @return
	 */
	public Response startAtOperation(Lot lot, String operation)
	{
		return lot.startAtOperation(operation);
	}
	
	/**
	 * 某个批次在某个工序上结束生产
	 * @param lot
	 * @param operation
	 * @return
	 */
	public Response completeAtOperation(Lot lot, String operation)
	{
		return lot.completeAtOperation(operation,null);
	}
	
	/**
	 * 在某个工序上结束当前批次，开始下一个批次
	 * @param lot
	 * @param operation
	 * @return
	 */
	public Response startNextLot(Lot lot, String operation)
	{
		Step step = lot.getPresentRouteStep();
		Queue queue = step.getQueue();
		Response response = lot.completeAtOperation(operation,null);
		if(response.isOk())
		{
			Lot nextLot = getOneLotInQueue(lot, queue);
			if(nextLot != null)
				return lot.startAtOperation(operation);
			else
			{
				return createErrorResponse(new Exception("No next lot"));
			}
		}
		else
		{
			return response;
		}
		
	}
	
	/**
	 * 保存物料消耗信息
	 * @param lot
	 * @param childLots
	 * @return Response
	 */
	public Response saveConsumption(Lot lot, Vector childLots)
	{
		Response response = new Response();
		if(childLots == null || childLots.size()==0)
			return response;
		try
		{
			ConsumptionSet consumptionSet = lot.createConsumptionSet();			
			for(int i=0;i<childLots.size();i++)
			{
				Lot childLot = (Lot)childLots.get(i);
				BomItem bomItem = getRuntimeBomItem(lot, childLot.getPartNumber());
				consumptionSet.addConsumedPart(bomItem, childLot, childLot.getPreciseQuantity());
			}
			response = consumptionSet.save(getFunctions().getDBTime(), false, false, false, null, null);
		}
		catch (Exception e)
		{
			response = createErrorResponse(e);
		}
		
		return response;
	}
	
	/**
	 * 创建一条数据采集记录
	 * @param lot
	 * @param dcsName
	 * @param values
	 * @param comment
	 * @return Response
	 */
	public Response createDCInstance(Lot lot, String dcsName, HashMap<String, Object> values, String comment)
	{
		RuntimeDCS runtimeDCS = lot.getDCS(dcsName);
		DCInstance dcInstance = runtimeDCS.createDCInstance();
		for (Iterator<String> iterator = values.keySet().iterator(); iterator.hasNext();)
		{
			String paraName = iterator.next();
			dcInstance.setValue(paraName, values.get(paraName));
			dcInstance.setComment(comment);
		}
		return runtimeDCS.save();

	}
	
	/**
	 * 清空DCSInstance
	 * @param lot
	 * @param step
	 */
	public void clearDCSInstance(Lot lot, Step step)
	{
		Vector dcs = step.getDataCollections();
		for (int i = 0; i < dcs.size(); i++)
		{
			DataCollectionSet dataCollectionSet = (DataCollectionSet) dcs.get(i);
			RuntimeDCS runtimeDCS = lot.getDCS(dataCollectionSet.getName());
			Vector dcInstances = runtimeDCS.getAllInstances();
			ArrayList<DCInstance> dciToRemove = new ArrayList<DCInstance>();
			for (int j = 0; j < dcInstances.size(); j++)
			{
				dciToRemove.add((DCInstance) dcInstances.get(j));
			}

			if (dciToRemove.size() > 0)
			{
				for (int j = 0; j < dciToRemove.size(); j++)
				{
					DCInstance dcInstance = dciToRemove.get(j);
					dcInstance.delete();
				}
			}
			runtimeDCS.save();
		}
	}
	
	private Lot getOneLotInQueue(Lot lot, Queue queue)
	{
		Lot oneLot = null;
		LotFilter lotFilter = getFunctions().createLotFilter();
		lotFilter.forOrderItemKeyEqualTo(lot.getOrderItemKey());
		lotFilter.forQueueKeyEqualTo(queue.getKey());
		lotFilter.orderByLotName(true);
		Vector lots = getFunctions().getFilteredLots(
			lotFilter);
		if(lots.size()>0)
		{
			oneLot = (Lot)lots.firstElement();
		}
		return oneLot;
	}
	
	private int getAllChildLotCount(Lot lot)
	{
		LotFilter lotFilter = getFunctions().createLotFilter();
		lotFilter.forOrderItemKeyEqualTo(lot.getOrderItemKey());
		lotFilter.addSearchBy(
			ILotFilterAttributes.NAME, IFilterComparisonOperators.NOT_EQUAL_TO, lot.getName());
		return getFunctions().getFilteredLotCount(
			lotFilter);
	}
	
	private BomItem getRuntimeBomItem(Lot lot, String partNumber)
	{
		Vector bomItems = lot.getAllBomItems();
		for (int i = 0; i < bomItems.size(); i++)
		{
			BomItem bomItemTemp = (BomItem) bomItems.get(i);
			if (bomItemTemp.getBomItemName().equals(
				partNumber))
			{
				return bomItemTemp;
			}
		}
		return null;
	}
	
	

}
